//hashMap.c

#include "hashMap.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

MAP * createMap(int size){
  int i;
  MAP *map=(MAP*)calloc(1,16);
  CHECK_ALC_ERROR(map);
  map->size=size;
  map->entries=(ENTRY**)calloc(size,16);
  CHECK_ALC_ERROR(map->entries);

  for(i=0;i<size;i++){
    map->entries[i]=NULL;
  }
  return map;
}



int insert(MAP *map, int key, void *value){
  int index; 
  ENTRY *new_entry=(ENTRY*)calloc(1,sizeof(ENTRY));
  ENTRY *entry;
  CHECK_ALC_ERROR(new_entry);
  new_entry->key=key;
  new_entry->val=value;

  //very simple hash func
  index=key%map->size;
  entry=map->entries[index];
  //entry is empty, lets insert new entry
  if(entry==NULL){
    map->entries[index]=new_entry;
    return 0;
  }
  //collision
  //lets do linear probing
  else{
    while(index<=map->size){
      //found no entries, map is full
      if(index==map->size)
	return -1;
      entry=map->entries[++index];
      if (entry==NULL)
	break;
      else if (entry->key==key)
	break;
    }

    map->entries[index]=new_entry;
    return 0;
  }
}




void * lookup(MAP *map, int key){
  ENTRY *entry;
  int index;
  index=key%map->size;
  entry=(map->entries)[index];
  
  //doesnt exist
  if (entry==NULL)
    return NULL;
  //bingo
  else if (entry->key==key){
    return entry->val;
  }
  
  //not the entry we're looking for
  //linear probe
  else{
   
    while(index<=map->size){
      //found no entries
      if(index==map->size || entry==NULL)
	return NULL;
      entry=(map->entries)[index++];
      if (entry->key==key)
	return entry->val;
    }
    return NULL;
    
  }
}

void * removeEntry(MAP *map, int key){
  ENTRY *entry;
  int index;
  char * value;
  index=key%map->size;
  entry=map->entries[index];
  
  //doesnt exist
  if (entry==NULL)
    return NULL;
  
  //bingo
  else if (entry->key==key){
    value=entry->val;
    entry=NULL;
    return value;
  }
  
  //not the entry we're looking for
  //linear probe
  else{
    while(index<map->size){
      entry=map->entries[++index];
      if(entry->key==key){
	value=entry->val;
	entry=NULL;
	return value;
      }
    }
    //couldn't find it
    return NULL;
    
  }
}

void freeMap(MAP* map){
  free(map->entries);
  free(map);
}

/*

//for debug hash map
int main(int argc,char* argv[],char* envp[]){
  MAP *ls=createMap(10);
  insert(ls,0,"ONE");
  insert(ls,1,"TWO");
  insert(ls,2,"THREE");
//getArray(ls);
  int i;
  for(i=0;i<3;i++){
    printf("%s\n",(char*)removeEntry(ls,i));
  }
  
}
*/
